package com.ray.exception;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ray.util.ExceptionUtil;
import com.ray.util.ResponseUtil;

public class ExceptionHandler implements HandlerExceptionResolver{
	static Logger logger = Logger.getLogger(ExceptionHandler.class);
	public ExceptionHandler() {
		super();
		// TODO Auto-generated constructor stub
	}

	@Override
	public ModelAndView resolveException(HttpServletRequest request,
			HttpServletResponse response, Object arg2, Exception exception) {
		ObjectMapper mapper = new ObjectMapper();
		try {
			logger.error(ExceptionUtil.getStackTrace(exception));
			logger.info(request.getContextPath()+":"+mapper.writeValueAsString(request.getParameterMap()));
		} catch (JsonProcessingException e1) {
			e1.printStackTrace();
		}
		String msg=exception.getMessage();
		if(null != msg && msg.indexOf("重定向错误")> -1 ) {
			String redirUrl=msg.substring(5,msg.length());
			System.out.println(redirUrl);
			return new ModelAndView("redirect:"+redirUrl);
		}else {
			// 判断是否ajax请求
			if (!(request.getHeader("accept").indexOf("application/json") > -1 || (request
					.getHeader("X-Requested-With") != null && request.getHeader(
							"X-Requested-With").indexOf("XMLHttpRequest") > -1))) {
				// 如果不是ajax，JSP格式返回
				// 为安全起见，只有业务异常我们对前端可见，否则否则统一归为系统异常  参数异常（断言机制）
				Map<String, Object> map = new HashMap<String, Object>();
				map.put(ResponseUtil.RESULT_KEY, ResponseUtil.ERROE);//设置result为false
				if (exception instanceof ServiceException || exception instanceof IllegalArgumentException) {//如果异常属于业务异常，异常信息传给info
					map.put(ResponseUtil.ERROR_INFO_KEY, exception.getMessage());
				} else {//否则info赋值为系统异常
					String mString="网络不好，请稍等。。。。。";
					if(msg != null && msg.indexOf("将截断字符串或二进制数据") > 0 ) {
						mString="字符过长" ;
					}
					map.put(ResponseUtil.ERROR_INFO_KEY,mString);
					
//            	if(exception.getMessage()==null || exception.getMessage().equals("")) {
//            		map.put(ResponseUtil.ERROR_INFO_KEY, "网络不好，请稍等。。。。。");
//            	}else {
//            		map.put(ResponseUtil.ERROR_INFO_KEY, exception.getMessage());
//            	}
				}
				//这里需要手动将异常打印出来，由于没有配置log，实际生产环境应该打印到log里面
				logger.error(exception.getMessage());
				exception.printStackTrace();
				//如果是文件上传
				if(request.getHeader("Content-Type")!=null&&request.getHeader("Content-Type").indexOf("multipart/form-data") > -1) {
					try {
						PrintWriter writer = response.getWriter();
						String json=mapper.writeValueAsString(map);
						writer.write(json);
						writer.flush();
						writer.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}else {
					//对于非ajax请求，都统一跳转到error.jsp页面
					// 为安全起见，业务异常对前端可见，否则统一归为系统异常
					if (exception instanceof ServiceException || exception instanceof IllegalArgumentException) {
						response.setContentType("application/json;charset=UTF-8");
						map.put(ResponseUtil.ERROR_INFO_KEY, exception.getMessage());
						String json;
						try {
							json = mapper.writeValueAsString(map);
							PrintWriter writer = response.getWriter();
							writer.write(json);
							writer.flush();
							writer.close();
						} catch (JsonProcessingException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					} else {
						response.setContentType("application/json;charset=UTF-8");
						map.put(ResponseUtil.ERROR_INFO_KEY, "网络不好，请稍等。。。。。");
						String json;
						try {
							json = mapper.writeValueAsString(map);
							PrintWriter writer = response.getWriter();
							writer.write(json);
							writer.flush();
							writer.close();
						} catch (JsonProcessingException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
					//return new ModelAndView("error", map);
				}
			} else {
				// 如果是ajax请求，JSON格式返回
				try {
					response.setContentType("application/json;charset=UTF-8");
					PrintWriter writer = response.getWriter();
					Map<String, Object> map = new HashMap<String, Object>();
					map.put(ResponseUtil.RESULT_KEY, ResponseUtil.ERROE);
					// 为安全起见，业务异常对前端可见，否则统一归为系统异常
					if (exception instanceof ServiceException || exception instanceof IllegalArgumentException) {
						map.put(ResponseUtil.ERROR_INFO_KEY, exception.getMessage());
					} else {
						String mString="网络不好，请稍等。。。。。";
						if(msg != null && msg.indexOf("将截断字符串或二进制数据") > 0 ) {
							mString="字符过长" ;
						}
						map.put(ResponseUtil.ERROR_INFO_KEY,mString);
//                	if(exception.getMessage()==null || exception.getMessage().equals("")) {
//                		map.put(ResponseUtil.ERROR_INFO_KEY, "网络不好，请稍等。。。。。");
//                	}else {
//                		map.put(ResponseUtil.ERROR_INFO_KEY, exception.getMessage());
//                	}
					}
					logger.error(exception.getMessage());
					String json=mapper.writeValueAsString(map);
					writer.write(json);
					writer.flush();
					writer.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}
}
